#include "fileidentitymanager.h"
#include <QCryptographicHash>
#include <QDebug>
#include <QMutex>
#include <QMutexLocker>
QString FileIdentityManager::getFileIdentity(const QString& filePath)
{
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        return QString();
    }
    // 标准化路径以避免重复缓存目录
    QString canonicalPath = fileInfo.canonicalFilePath();
    if (canonicalPath.isEmpty()) {
        // 如果无法获取canonical path，使用absolute path作为备选
        canonicalPath = fileInfo.absoluteFilePath();
    }
    QString fingerprint = generateFingerprint(fileInfo);
    QString identity = QString("%1_%2").arg(canonicalPath).arg(fingerprint);
    return identity;
}
bool FileIdentityManager::isFileChanged(const QString& filePath, const QString& lastIdentity)
{
    if (lastIdentity.isEmpty()) {
        return true; // 没有上次标识，认为已变更
    }
    QString currentIdentity = getFileIdentity(filePath);
    if (currentIdentity.isEmpty()) {
        return true; // 文件不存在，认为已变更
    }
    bool changed = (currentIdentity != lastIdentity);
    if (changed) {
    }
    return changed;
}
QString FileIdentityManager::getCacheKey(const QString& fileIdentity)
{
    if (fileIdentity.isEmpty()) {
        return QString();
    }
    // 使用MD5哈希生成缓存键，确保目录名安全
    QCryptographicHash hash(QCryptographicHash::Md5);
    hash.addData(fileIdentity.toUtf8());
    QString cacheKey = hash.result().toHex();
    // **重要修复**: 线程安全的调试日志记录
    static QMutex logMutex;
    static QSet<QString> loggedKeys;
    {
        QMutexLocker locker(&logMutex);
        if (!loggedKeys.contains(cacheKey)) {
            loggedKeys.insert(cacheKey);
        }
    }
    return cacheKey;
}
QString FileIdentityManager::getDisplayName(const QString& fileIdentity)
{
    if (fileIdentity.isEmpty()) {
        return QString();
    }
    QHash<QString, QString> parts = parseIdentity(fileIdentity);
    QString filePath = parts.value("path");
    if (filePath.isEmpty()) {
        return QString();
    }
    QFileInfo fileInfo(filePath);
    return fileInfo.fileName();
}
QString FileIdentityManager::getFilePath(const QString& fileIdentity)
{
    if (fileIdentity.isEmpty()) {
        return QString();
    }
    QHash<QString, QString> parts = parseIdentity(fileIdentity);
    return parts.value("path");
}
bool FileIdentityManager::isValidIdentity(const QString& fileIdentity)
{
    if (fileIdentity.isEmpty()) {
        return false;
    }
    QHash<QString, QString> parts = parseIdentity(fileIdentity);
    QString filePath = parts.value("path");
    if (filePath.isEmpty()) {
        return false;
    }
    QFileInfo fileInfo(filePath);
    return fileInfo.exists();
}
QString FileIdentityManager::getFileType(const QString& filePath)
{
    QFileInfo fileInfo(filePath);
    QString suffix = fileInfo.suffix().toLower();
    if (suffix == "pdf") {
        return "pdf";
    } else if (QStringList{"jpg", "jpeg", "png", "bmp", "gif", "tiff", "webp"}.contains(suffix)) {
        return "image";
    }
    return "unknown";
}
QString FileIdentityManager::generateFingerprint(const QFileInfo& fileInfo)
{
    // 使用标准化路径生成指纹，避免路径差异导致的重复缓存
    QString canonicalPath = fileInfo.canonicalFilePath();
    if (canonicalPath.isEmpty()) {
        canonicalPath = fileInfo.absoluteFilePath();
    }
    // 生成基于元数据的指纹：标准化路径+修改时间+大小+类型
    QString fingerprint = QString("%1_%2_%3_%4")
        .arg(canonicalPath)
        .arg(fileInfo.lastModified().toString(Qt::ISODate))
        .arg(fileInfo.size())
        .arg(fileInfo.suffix().toLower());
    // 对指纹进行MD5哈希，确保长度固定且安全
    QCryptographicHash hash(QCryptographicHash::Md5);
    hash.addData(fingerprint.toUtf8());
    return hash.result().toHex();
}
QHash<QString, QString> FileIdentityManager::parseIdentity(const QString& fileIdentity)
{
    QHash<QString, QString> result;
    // 解析格式：/absolute/path_fingerprint
    int lastUnderscore = fileIdentity.lastIndexOf('_');
    if (lastUnderscore > 0) {
        QString filePath = fileIdentity.left(lastUnderscore);
        QString fingerprint = fileIdentity.mid(lastUnderscore + 1);
        result["path"] = filePath;
        result["fingerprint"] = fingerprint;
        // 验证路径是否存在
        QFileInfo fileInfo(filePath);
        if (fileInfo.exists()) {
            result["mtime"] = fileInfo.lastModified().toString(Qt::ISODate);
            result["size"] = QString::number(fileInfo.size());
            result["type"] = fileInfo.suffix().toLower();
        }
    }
    return result;
}
